package top.chenyaohua.visit;

import jdk.internal.org.objectweb.asm.*;

import java.util.*;

public class PnuMethodVisitor extends MethodVisitor {

    private Type[] paramsTypes;

    private LinkedHashMap<Integer,String> params = new LinkedHashMap<>();


    public PnuMethodVisitor (MethodVisitor visitMethod, Type[] paramsTypes) {
        super(327680, visitMethod);
        this.paramsTypes = paramsTypes;
    }

    /**
     * 访问方法一个参数
     * @param s
     * @param i
     */
    @Override
    public void visitParameter (String s, int i) {
        super.visitParameter(s, i);
    }
    /**
     * 域操作指令，用来加载或者存储对象的Field；
     */
    @Override
    public void visitFieldInsn (int i, String s, String s1, String s2) {
        super.visitFieldInsn(i, s, s1, s2);
    }

    /**
     * 访问方法操作指令
     * @param i
     * @param s
     * @param s1
     * @param s2
     * @param b
     */
    @Override
    public void visitMethodInsn (int i, String s, String s1, String s2, boolean b) {
        super.visitMethodInsn(i, s, s1, s2, b);
    }

    /**
     * 访问方法局部变量的当前状态以及操作栈成员信息，方法栈必须是expanded 格式或者compressed格式,该方法必须在visitInsn方法前调用;
     * @param i
     * @param i1
     * @param objects
     * @param i2
     * @param objects1
     */
    @Override
    public void visitFrame (int i, int i1, Object[] objects, int i2, Object[] objects1) {
        super.visitFrame(i, i1, objects, i2, objects1);
    }

    /**
     * 访问本地变量描述;
     * @param s
     * @param s1
     * @param s2
     * @param label
     * @param label1
     * @param i
     */
    @Override
    public void visitLocalVariable (String s, String s1, String s2, Label label, Label label1, int i) {
        params.put(i,s);
        super.visitLocalVariable(s, s1, s2, label, label1, i);
    }

    /**
     * 访问注解接口方法的默认值；
     * @return
     */
    @Override
    public AnnotationVisitor visitAnnotationDefault () {
        return super.visitAnnotationDefault();
    }

    /**
     * 访问域的注解；
     * @param s
     * @param b
     * @return
     */
    @Override
    public AnnotationVisitor visitAnnotation (String s, boolean b) {
        return super.visitAnnotation(s, b);
    }

    /**
     * 访问域的类型上的注解
     * @param i
     * @param typePath
     * @param s
     * @param b
     * @return
     */
    @Override
    public AnnotationVisitor visitTypeAnnotation (int i, TypePath typePath, String s, boolean b) {
        return super.visitTypeAnnotation(i, typePath, s, b);
    }

    /**
     * 访问参数的注解，返回一个AnnotationVisitor可以访问该注解值;
     * @param i
     * @param s
     * @param b
     * @return
     */
    @Override
    public AnnotationVisitor visitParameterAnnotation (int i, String s, boolean b) {
        return super.visitParameterAnnotation(i, s, b);
    }

    /**
     * 访问方法属性；
     * @param attribute
     */
    @Override
    public void visitAttribute (Attribute attribute) {
        super.visitAttribute(attribute);
    }

    /**
     * 开始访问方法代码，此处可以添加方法运行前拦截器;
     */
    @Override
    public void visitCode () {
        super.visitCode();
    }

    /**
     *
     * @param i
     */
    @Override
    public void visitInsn (int i) {
        super.visitInsn(i);
    }

    /**
     * 访问数值类型指令
     * @param i
     * @param i1
     */
    @Override
    public void visitIntInsn (int i, int i1) {
        super.visitIntInsn(i, i1);
    }

    /**
     * 访问本地变量类型指令
     * @param i
     * @param i1
     */
    @Override
    public void visitVarInsn (int i, int i1) {
        super.visitVarInsn(i, i1);
    }

    /**
     * 访问类型指令，类型指令会把类的内部名称当成参数Type
     * @param i
     * @param s
     */
    @Override
    public void visitTypeInsn (int i, String s) {
        super.visitTypeInsn(i, s);
    }

    /**
     * 访问方法操作指令
     * @param i
     * @param s
     * @param s1
     * @param s2
     */
    @Override
    public void visitMethodInsn (int i, String s, String s1, String s2) {
        super.visitMethodInsn(i, s, s1, s2);
    }

    @Override
    public void visitInvokeDynamicInsn (String s, String s1, Handle handle, Object... objects) {
        super.visitInvokeDynamicInsn(s, s1, handle, objects);
    }

    /**
     * 访问比较跳转指令;
     * @param i
     * @param label
     */
    @Override
    public void visitJumpInsn (int i, Label label) {
        super.visitJumpInsn(i, label);
    }

    /**
     *
     * @param label
     */
    @Override
    public void visitLabel (Label label) {
        super.visitLabel(label);
    }

    /**
     * 访问ldc指令，也就是访问常量池索引；
     * @param o
     */
    @Override
    public void visitLdcInsn (Object o) {
        super.visitLdcInsn(o);
    }

    /**
     * 访问本地变量索引增加指令;
     * @param i
     * @param i1
     */
    @Override
    public void visitIincInsn (int i, int i1) {
        super.visitIincInsn(i, i1);
    }

    /**
     * 访问跳转指令；
     * @param i
     * @param i1
     * @param label
     * @param labels
     */
    @Override
    public void visitTableSwitchInsn (int i, int i1, Label label, Label... labels) {
        super.visitTableSwitchInsn(i, i1, label, labels);
    }

    /**
     * 访问查询跳转指令;
     * @param label
     * @param ints
     * @param labels
     */
    @Override
    public void visitLookupSwitchInsn (Label label, int[] ints, Label[] labels) {
        super.visitLookupSwitchInsn(label, ints, labels);
    }

    /**
     * 访问多维数组指令;
     * @param s
     * @param i
     */
    @Override
    public void visitMultiANewArrayInsn (String s, int i) {
        super.visitMultiANewArrayInsn(s, i);
    }

    /**
     * 访问指令注解，必须在访问注解之后调用;
     * @param i
     * @param typePath
     * @param s
     * @param b
     * @return
     */
    @Override
    public AnnotationVisitor visitInsnAnnotation (int i, TypePath typePath, String s, boolean b) {
        return super.visitInsnAnnotation(i, typePath, s, b);
    }

    /**
     * 方法try--catch块；
     * @param label
     * @param label1
     * @param label2
     * @param s
     */
    @Override
    public void visitTryCatchBlock (Label label, Label label1, Label label2, String s) {
        super.visitTryCatchBlock(label, label1, label2, s);
    }

    /**
     * 访问try...catch块上异常处理的类型注解，必须在调用visitTryCatchBlock之后调用;
     * @param i
     * @param typePath
     * @param s
     * @param b
     * @return
     */
    @Override
    public AnnotationVisitor visitTryCatchAnnotation (int i, TypePath typePath, String s, boolean b) {
        return super.visitTryCatchAnnotation(i, typePath, s, b);
    }

    @Override
    public AnnotationVisitor visitLocalVariableAnnotation (int i, TypePath typePath, Label[] labels, Label[] labels1, int[] ints, String s, boolean b) {
        return super.visitLocalVariableAnnotation(i, typePath, labels, labels1, ints, s, b);
    }

    /**
     * 访问行号描述；
     * @param i
     * @param label
     */
    @Override
    public void visitLineNumber (int i, Label label) {
        super.visitLineNumber(i, label);
    }

    @Override
    public void visitMaxs (int i, int i1) {
        super.visitMaxs(i, i1);
    }

    @Override
    public void visitEnd () {
        super.visitEnd();
    }

    public Type[] getParamsTypes () {
        return paramsTypes;
    }

    public LinkedHashMap<Integer, String> getParams () {
        return params;
    }


}
